from .mathematic import Pi as _Pi, Factorial as _Factorial, FFactorial as _FFactorial
from sympy import exp as _exp

def P(m: int, n: int) -> int:
    """排列Arrangement,从n中选m个"""
    return _Factorial(n)/_Factorial(n-m)


def C(k: int, n: int) -> int:
    """组合Combination,从n中选k个"""
    return _Factorial(n)/_Factorial(k)/_Factorial(n-k)


def P_F(m: int, n: int) -> int:
    """排列Arrangement,从n中选m个\n
    浮点数版本"""
    return _FFactorial(n)/_FFactorial(n-m)


def C_F(k: int, n: int) -> int:
    """组合Combination,从n中选k个\n
    浮点数版本"""
    return _FFactorial(n)/_FFactorial(k)/_FFactorial(n-k)


def normalDistribution(t: float, mu: float = 0, sigma: float = 1) -> float:
    """正态分布"""
    L, ex = 1/(2*_Pi)**0.5/sigma, -(t-mu)**2/2/sigma**2
    return L*_exp(ex)


def poissonDistribution(k: float, lamda: float=1) -> float:
    """泊松分布"""
    return (lamda**k)*_exp(-lamda)/_FFactorial(k)


def exponentialDistribution(x: float, theta: float = 1) -> float:
    """指数分布"""
    return _exp(-x/theta)/theta


def binomialDistribution(x: int, n: int, p: float = 0.5) -> float:
    """二项分布"""
    return C_F(x, n)*p**x*(1-p)**(n-x)


def average(lst: list) -> float:
    """平均值"""
    return sum(lst)/len(lst)


def deviationVar(lst: list) -> float:
    """方差"""
    return average([i**2 for i in lst])-average(lst)**2


def deviationStandard(lst: list) -> float:
    """标准差"""
    return deviationVar(lst)**0.5


def convariance(lst1: list, lst2: list) -> float:
    """协方差"""
    return average([x*y for x, y in zip(lst1, lst2)])-average(lst1)*average(lst2)


def correlationCoefficient(lst1: list, lst2: list) -> float:
    """相关系数"""
    return convariance(lst1, lst2)/deviationStandard(lst1)/deviationStandard(lst2)


def successfulDifference(lst: list, dx: list) -> float:
    """逐差法"""
    ll = [lst[i+dx]-lst[i] for i in range(len(lst)-dx)]
    return average(ll)/dx


def bessel(lst: list) -> float:
    '''贝塞尔公式计算标准差'''
    ex = average(lst)
    return (sum((x-ex)**2 for x in lst)/(len(lst)-1))**0.5
